#include "uihelper.h"
#include "util.h"
#include "tinyxml/tinystr.h"
#include "tinyxml/tinyxml.h"

using namespace UIHelper;
void UIHelper::List::render( int x /*= -1*/, int y /*= -1 */ )
{
	selectionx = 0;
	selectiony = 0;
	if( x == -1 )
		x = area.x;
	if( y== -1 )
		y = area.y;
	renderRectangle(x, y, x+area.width, y+area.height,backcolor,true);
	if( renderedge )
		renderRectangle(x, y, x+area.width, y+area.height,forcolor);
	if( contents.size() == 0 )
		return;
	int selectionrow = selection/column;
	int rownumber = area.height/font->GetHeight();
	if( selectionrow < startrow )
		startrow = selectionrow;
	if( startrow+rownumber <= selectionrow )
		startrow = selectionrow-rownumber+1;
	int startindex = startrow*column;
	int endindex = (startrow+rownumber)*column;
	if( startindex >= contents.size() )
		startindex = contents.size() - 1;
	if( endindex > contents.size() )
		endindex = contents.size();
	int xlen = area.width/column;
	int ylen = area.height/rownumber;//font->GetHeight();
	for( int i=startindex;i<endindex;i++ )
	{
		int stringwidth = font->GetStringWidth(contents[i].c_str());
		int xstart = x+1+xlen*(i%column);
		int ystart = y+1+ylen*(i/column - startrow);
		if( align == center )
		{
			xstart += (xlen-stringwidth)/2;
			ystart += (ylen - font->GetHeight())/2;
		}
		if( selection == i && hideselection == false )
		{
			renderRectangle( xstart-1, ystart-1, xstart+stringwidth+1, ystart+font->GetHeight()+1, forcolor, true );
			int color = font->GetColor();
			font->SetColor(backcolor);
			font->Print(xstart,ystart,contents[i].c_str());
			font->SetColor(color);
			selectionx = xstart;
			selectiony = ystart;
		}
		else
		{
			font->Print(xstart,ystart,contents[i].c_str());
		}
	}
	
}

int UIHelper::List::update()
{
	if( contents.size() == 0 )
	{
		selection = -1;
	}
	if( hge->Input_KeyDown(HGEK_ENTER) )
		return entered;
	else if( hge->Input_KeyDown(HGEK_Q) )
		return escaped;
	else if( hge->Input_KeyDown(HGEK_DOWN) )
		selection += column;
	else if( hge->Input_KeyDown(HGEK_RIGHT) && column>1 )
		selection += 1;
	else if( hge->Input_KeyDown(HGEK_UP) )
		selection -= column;
	else if( hge->Input_KeyDown(HGEK_LEFT) && column>1 )
		selection -= 1;
	if( selection < 0 )
		selection = contents.size() - 1;
	if( selection >= contents.size() )
		selection = 0;
	return common;
}

void UIHelper::List::add( std::string str, int itemdata /*= 0 */ )
{
	contents.push_back( str );
	itemdatas.push_back( itemdata );
}

void UIHelper::List::set( int index, std::string str, int itemdata /*= 0 */ )
{
	if( contents.size() <= index )
		return;
	contents[index] = str;
	itemdatas[index] = itemdata;
}

const char* UIHelper::List::getstr( int index )
{
	if( contents.size() <= index )
		return 0;
	return contents[index].c_str();
}

int UIHelper::List::getitemdata( int index )
{
	if( index == -1 )
		index = selection;
	if( contents.size() <= index )
		return 0;
	return itemdatas[index];
}

void UIHelper::List::remove( int index )
{
	if( contents.size() <= index )
		return;
	contents.erase( contents.begin() + index );
	itemdatas.erase( itemdatas.begin() + index );
}

int UIHelper::List::getcount()
{
	return contents.size();
}

void UIHelper::List::clear()
{
	contents.clear();
	itemdatas.clear();
}

void UIHelper::List::reset()
{
	selection = 0;
	column = 1;
	startrow = 0;
	backcolor = screen_backcolor;
	forcolor = 0xff000000;
	align = center;
	renderedge = true;
	clear();
}

void UIHelper::List::initwithconfig( const char *configname )
{
	WidgetDef *def = GetWidgetDef(configname);
	area = gcn::Rectangle(def->x, def->y, def->w, def->h );
	renderedge = def->edge==1;
	column = def->column;
	backcolor = def->backcolor;
	forcolor = def->forcolor;
	align = def->align;
	for( int i=0; i<def->items.size(); i++ )
	{
		add(def->items[i]);
	}
}

void UIHelper::TextBox::render( int x /*= -1*/, int y /*= -1 */ )
{
	if( x == -1 )
		x = area.x;
	if( y== -1 )
		y = area.y;
	renderRectangle(x, y, x+area.width, y+area.height,backcolor,true);
	if( drawedge )
		renderRectangle(x, y, x+area.width, y+area.height,forcolor);
	if( contents.size() == 0 )
		return;
	int rownumber = area.height/font->GetHeight();

	int startindex = page*rownumber;
	int endindex = startindex+rownumber;
	if( startindex >= contents.size() )
		startindex = contents.size() - 1;
	if( endindex > contents.size() )
		endindex = contents.size();
	int ylen = font->GetHeight();
	for( int i=startindex;i<endindex;i++ )
	{
		int xstart = x+1;
		int ystart = y+1+ylen*(i-startindex);
		font->Print(xstart,ystart,contents[i].c_str());
	}
}

int UIHelper::TextBox::update()
{
	int rownumber = area.height/font->GetHeight();
	int pagenum = 1 + contents.size()/rownumber;
	if( hge->Input_KeyDown(HGEK_DOWN) )
		page++;
	else if( hge->Input_KeyDown(HGEK_UP) )
		page--;
	if( page<0 )
		page=0;
	if( page>= pagenum )
		page = pagenum - 1;
	return 0;
}

void UIHelper::TextBox::addline( std::string str )
{
	int texwidth = font->GetStringWidth(str.c_str());
	int charperline = float(str.length())*float(area.width)/float(texwidth);
	if( charperline == 0 )
	{
		contents.push_back( str );
		return;
	}
	int startpoint = 0;
	while( startpoint < str.length() )
	{
		std::string divided = FontCnUtility::DivideString( str, startpoint, charperline );
		contents.push_back( divided );
	}
}

void UIHelper::TextBox::initwithconfig( const char *configname )
{
	WidgetDef *def = GetWidgetDef(configname);
	area = gcn::Rectangle(def->x, def->y, def->w, def->h );
	drawedge = def->edge==1;
	backcolor = def->backcolor;
	forcolor = def->forcolor;
	for( int i=0; i<def->items.size(); i++ )
	{
		addline(def->items[i]);
	}
}

void UIHelper::TextBox::reset()
{
	contents.clear();
}

void UIHelper::Load()
{
	const char *filename = "data\\UI.xml";
	TiXmlDocument doc;
	if( !doc.LoadFile(filename) )
		return;
	for( TiXmlElement *node = doc.RootElement(); node!=NULL;  node = node->NextSiblingElement() )
	{
		const char *name = node->Value();
		if( name == 0 )
			continue;
		WidgetDef *def = new WidgetDef;
		def->x = GetXmlInteger( node, "x" );
		def->y = GetXmlInteger( node, "y" );
		def->w = GetXmlInteger( node, "w" );
		def->h = GetXmlInteger( node, "h" );
		def->edge = GetXmlInteger( node, "edge", 1 );
		def->column = GetXmlInteger( node, "column", 1 );
		def->backcolor = GetXmlInteger( node, "backcolor", screen_backcolor );
		def->forcolor = GetXmlInteger( node, "forcolor", 0xff000000 );
		def->align = GetXmlInteger( node, "align", List::center );
		for( TiXmlElement *itemnode = node->FirstChildElement("item"); itemnode!=0; itemnode = itemnode->NextSiblingElement("item") )
		{
			const char *text = itemnode->GetText();
			if( text )
				def->items.push_back( text );
		}
		widgetmap[name] = def;
	}
}

UIHelper::WidgetDef * UIHelper::GetWidgetDef( std::string key )
{
	static WidgetDef defaultdef;
	WidgetDefMap::iterator iter = widgetmap.find(key);
	if( iter != widgetmap.end() )
		return iter->second;
	return &defaultdef;
}